
#include "ka-system/context.h"
#include "ka-system/event.h"

using namespace ka;

ThreadLocal Context::_threadLocal;

Context::Context()
: _base(NULL),
_shadowed(false) {
    _base = reinterpret_cast<Context *>(_threadLocal.getPointer());
    _threadLocal.setPointer(this);
    if (_base) {
        _base->_shadowed = true;
    }
}

Context::~Context() {
    _threadLocal.setPointer(_base);
    if (_base) {
        _base->_shadowed = false;
        for (size_t i=0; i<_handlerSlots.size(); ++i) {
            EventHandler *h = _handlerSlots[i];
            while (h) {
                EventHandler *n = h->getNext();
                h->removeFromContext();
                h = n;
            }
        }
    }
}

Context *Context::getCurrent() {
    return reinterpret_cast<Context *>(_threadLocal.getPointer());
}

int Context::getEventChannel(const UUID &eventUid) const {
    int r = -1;
    for (int i=0; i<_handlerSlots.size(); ++i) {
        EventHandler *h = _handlerSlots[i];
        if (h != NULL && h->getEventUid()==eventUid) {
            r = i;
            break;
        }
    }
    return r;
}

EventHandler *Context::getEventHandlers(int eventChannel) const {
    EventHandler *r = NULL;
    if (eventChannel >= 0 && eventChannel<_handlerSlots.size()) {
        r = _handlerSlots[eventChannel];
    }
    return r;
}

int Context::setEventHandlers(EventHandler *eventHandler) {
    int r = -1;
    if (eventHandler) {
        r = getEventChannel(eventHandler->getEventUid());
        if (r == -1) {
            _handlerSlots.push_back(NULL);
            r = _handlerSlots.size()-1;
        }
        _handlerSlots[r] = eventHandler;
    }
    return r;
}


IContextManifest::~IContextManifest() {

}